package cn.anlaser.utils;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.UUID;

import org.apache.commons.fileupload.FileItem;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import cn.anlaser.config.FileServerConfig;
import cn.anlaser.exception.NutException;
import cn.anlaser.form.UploadFileForm;
import cn.anlaser.type.FileTypeEnum;
import cn.anlaser.type.GenFileName;
import cn.wsalix.utils.Utils;

public class HttpUtils {
	private static final Logger logger = LoggerFactory
			.getLogger(HttpUtils.class);
	public static String defaultCharset = "UTF-8";

	public static String getSessionnId(HttpResponse httpResponse) {
		String setCookie = httpResponse.getFirstHeader("Set-Cookie").getValue();
		String JSESSIONID = setCookie.substring("JSESSIONID=".length(),
				setCookie.indexOf(";"));
		return JSESSIONID;
	}

	/**
	 * @seee UploadFileAction.add
	 * @param fsConfig
	 * @param file
	 * @param form
	 */
	public static String[] uploadFiles(FileServerConfig fsConfig,
			MultipartFile[] files) {
		if (files != null && files.length > 0) {
			String[] returnLine = new String[files.length];
			int i = 0;
			for (MultipartFile file : files) {
				returnLine[i++] = saveFile(file, fsConfig);
			}
			return returnLine;
		} else {
			throw new NutException("文件上传失败");
		}

	}

	public static String saveFile(MultipartFile file, FileServerConfig fsConfig) {
		try {
			String distFileName = getFileName(fsConfig.getGenFileName(),
					fsConfig, file.getOriginalFilename());
			File distFile = null;
			distFile = saveRealFile(fsConfig, "multipart_file", distFileName);
			file.transferTo(distFile);
			String fpath = distFile.getPath().replace("\\", "/");
			fpath = fsConfig.getHttpPrix()
					+ fpath.substring(fpath.indexOf("upload"));
			return fpath;
		} catch (Exception e) {
			e.printStackTrace();
			throw new NutException("文件上传失败");
		}
	}

	public static void uploadFile(FileServerConfig fsConfig,
			MultipartFile file, UploadFileForm form) {
		if (!file.isEmpty()) {
			try {
				String distFileName = getFileName(fsConfig.getGenFileName(),
						fsConfig, file.getOriginalFilename());
				File distFile = null;
				/*
				 * distFile = saveRealFile(fsConfig,form.getType().name(), file,
				 * distFileName);
				 */
				distFile = saveRealFile(fsConfig, form.getType().getCode(),
						distFileName);
				file.transferTo(distFile);
				String fpath = distFile.getPath().replace("\\", "/");
				fpath = fpath.substring(fpath.indexOf("upload"));
				fpath = fsConfig.getHttpPrix() + fpath;
				form.setDistFile(distFile);
				form.setSavePath(distFile.getPath());
				form.setHttpUrl(fpath);
			} catch (Exception e) {
				e.printStackTrace();
				throw new NutException("文件上传失败");
			}
		}
	}

	public static String uploadFile(FileServerConfig fsConfig,
			MultipartFile file, FileTypeEnum type) {
		if (!file.isEmpty()) {
			try {
				String distFileName = getFileName(fsConfig.getGenFileName(),
						fsConfig, file.getOriginalFilename());
				File distFile = null;
				/*
				 * distFile = saveRealFile(fsConfig,form.getType().name(), file,
				 * distFileName);
				 */
				distFile = saveRealFile(fsConfig, type.getCode(), distFileName);
				file.transferTo(distFile);
				String fpath = distFile.getPath().replace("\\", "/");
				fpath = fpath.substring(fpath.indexOf("upload"));
				fpath = fsConfig.getHttpPrix() + fpath;
				/*
				 * form.setDistFile(distFile);
				 * form.setSavePath(distFile.getPath());
				 */
				return fpath;
			} catch (Exception e) {
				e.printStackTrace();
				throw new NutException("文件上传失败");
			}
		}
		return null;
	}

	static Calendar nowDate = Calendar.getInstance();

	private static File saveRealFile(FileServerConfig fsConfig, String type,
			String distFileName) throws IllegalStateException, IOException {
		String midPath = type + File.separator + nowDate.get(Calendar.YEAR)
				+ File.separator + (nowDate.get(Calendar.MONTH) + 1)
				+ File.separator// 月份需加一
				+ nowDate.get(Calendar.DAY_OF_MONTH);
		if (fsConfig.getServerType().equals("local")) {

			File dirFile = new File(fsConfig.getSaveDir() + File.separator
					+ midPath);
			File distFile = new File(dirFile, distFileName
					+ Utils.nextInt(1000, 9999));
			if (!dirFile.canWrite()) {
				dirFile.mkdirs();
			}
			// 文件保存路径
			/*
			 * String filePath =
			 * request.getSession().getServletContext().getRealPath("/") +
			 * "upload/" + file.getOriginalFilename();
			 */
			// 转存文件

			logger.info("upload file to:" + dirFile.getPath() + File.separator
					+ distFile.getName());
			//
			return distFile;
		}
		return null;
	}

	private static String getFileName(GenFileName genFileName,
			FileServerConfig fsConfig, String fileName) {
		String distFileName = "";
		switch (genFileName) {
		case original:
			distFileName = fileName;
			break;
		case timestamp:
			distFileName = System.currentTimeMillis() + "";
			break;
		case appoint:
			distFileName = fsConfig.getFileName();
			break;
		default:
			distFileName = UUID.randomUUID().toString();
			break;
		}
		return distFileName;
	}

	public static String[] saveFile(FileServerConfig fsConfig,
			MultipartFile[] files, String type) {
		String[] resArr = new String[files.length];
		int i = 0;
		for (MultipartFile file : files) {
			if (!file.isEmpty()) {
				try {
					// String filePath = "C:\\httpd-2.2-x64\\htdocs\\upload";
					String distFileName = "";
					File distFile = null;
					switch (fsConfig.getGenFileName()) {
					case original:
						distFileName = file.getOriginalFilename();
						break;
					case timestamp:
						distFileName = System.currentTimeMillis() + "";
						break;
					case appoint:
						distFileName = fsConfig.getFileName();
						break;
					default:
						distFileName = UUID.randomUUID().toString();
						break;
					}

					// switch (fsConfig.getServerType()) {
					// case Local:
					// File dirFile = new File(fsConfig.getSaveDir());
					// distFile = new File(dirFile, distFileName
					// + Utils.nextInt(1000, 9999));
					// if (!dirFile.canWrite()) {
					// dirFile.mkdirs();
					// }
					// // 文件保存路径
					// /*
					// * String filePath =
					// * request.getSession().getServletContext
					// * ().getRealPath("/") + "upload/" +
					// * file.getOriginalFilename();
					// */
					// // 转存文件
					// file.transferTo(distFile);
					// break;
					// case Ftp:
					// break;
					// default:
					// break;
					// }

					// add by jack at 20151013 返回相对路径
					distFile = saveRealFile(fsConfig, type, distFileName);
					file.transferTo(distFile);
					String fpath = distFile.getPath().replace("\\", "/");
					fpath = fpath.substring(fpath.indexOf("upload"));
					fpath = fsConfig.getHttpPrix() + fpath;
					resArr[i++] = fpath;

					// resArr[i++] = fsConfig.getHttpPrix() +
					// distFile.getName();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		for (String str : resArr) {
			logger.info(",........................" + str);
		}
		return resArr;
	}

	public static HttpResponse post(String url, HttpEntity entity,
			HttpHost target) {
		// 创建HttpClientBuilder
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		// HttpClient
		CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
		// 依次是目标请求地址，端口号,协议类型
		if (target != null) {

		}

		RequestConfig reqConfig = RequestConfig.custom().build();
		// 请求地址
		HttpPost httpPost = new HttpPost(url);
		httpPost.setConfig(reqConfig);
		try {
			httpPost.setEntity(entity);
			CloseableHttpResponse response = closeableHttpClient
					.execute(httpPost);
			// closeableHttpClient.close();
			return response;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static HttpResponse post(String url, HttpEntity entity,
			String sessionId) {
		// 创建HttpClientBuilder
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		// HttpClient
		CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
		// 依次是目标请求地址，端口号,协议类型
		RequestConfig reqConfig = RequestConfig.custom().build();
		// 请求地址
		HttpPost httpPost = new HttpPost(url);
		httpPost.setConfig(reqConfig);
		if (sessionId != null && !sessionId.equals("")) {
			httpPost.setHeader("Cookie", "JSESSIONID=" + sessionId);
		}
		try {
			httpPost.setEntity(entity);
			CloseableHttpResponse response = closeableHttpClient
					.execute(httpPost);
			// closeableHttpClient.close();
			return response;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static HttpResponse post(String url, HttpEntity entity) {
		return post(url, entity, "");
	}

	public static HttpResponse get(String url) {
		return get(url, "");
	}

	public static HttpResponse get(String url, String host, int port,
			String username, String password) {
		CloseableHttpClient client = HttpClients.custom().build();
		CredentialsProvider credsProvider = new BasicCredentialsProvider();
		credsProvider.setCredentials(new AuthScope(host, port),
				new UsernamePasswordCredentials(username, password));
		HttpClientContext context = HttpClientContext.create();
		context.setCredentialsProvider(credsProvider);
		/*
		 * context.setAuthSchemeRegistry(authRegistry);
		 * context.setAuthCache(authCache);
		 */
		HttpGet httpGet = new HttpGet(url);
		try {
			return client.execute(httpGet, context);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public static HttpResponse get(String url, String sessionId) {
		CloseableHttpClient client = HttpClients.custom().build();
		HttpGet httpGet = new HttpGet(url);
		if (sessionId != null && !sessionId.equals("")) {
			httpGet.setHeader("Cookie", "JSESSIONID=" + sessionId);
		}
		try {
			return client.execute(httpGet);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public static String getToString(String url) {
		return getToString(url, "");
	}

	public static String getToString(String url, String sessionId) {
		HttpResponse response = get(url, sessionId);
		try {
			return EntityUtils.toString(response.getEntity(), defaultCharset);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return url;
	}

	public static UploadFileForm uploadFile(FileServerConfig fsConfig,
			FileItem item, UploadFileForm form) {
		// TODO Auto-generated method stub
		if (item != null) {
			try {
				String distFileName = getFileName(fsConfig.getGenFileName(),
						fsConfig, item.getName());
				File distFile = null;
				/*
				 * distFile = saveRealFile(fsConfig,form.getType().name(), file,
				 * distFileName);
				 */
				distFile = saveRealFile(fsConfig, form.getType().getCode(),
						distFileName);
				item.write(distFile);
				String fpath = distFile.getPath().replace("\\", "/");
				fpath = fpath.substring(fpath.indexOf("upload"));
				fpath = fsConfig.getHttpPrix() + fpath;
				form.setDistFile(distFile);
				form.setSavePath(distFile.getPath());
				form.setHttpUrl(fpath);
			} catch (Exception e) {
				e.printStackTrace();
				throw new NutException("文件上传失败");
			}
		} else {
			throw new NutException("文件上传失败");
		}
		return form;
	}

}
